PukiWiki改造 その2 (管理者機能)
概要:HPの公開用としてログインした管理者のみがページの追加・編集・削除を出来るようにする。
pukiwiki.ini.phpの$edit_auth = 1の設定と併用してよりセキュリティーを高める。
また、後ページにあるように管理者用の機能を追加する時や管理者用のボタン表示をする時に利用する。
- 管理者用のログイン画面を表示し、ログインする。
- ログインのステータスをセッションに保存する。
- ログイン出来た場合のみ、追加・編集・削除などの操作が出来るようにする。
- ログインできるクライアントをIPアドレスで限定し、ユーザーIDとパスワードをIPアドレス毎に設定する。
- IPアドレスが固定で無い場合は、IPアドレスの限定なしでユーザーIDとパスワードでログインできるようにも設定できる。
- 各プラグインに変更を加えるので共通関数を作成する。
注:ここではセキュリティー上あまり詳細を記述していない。
1. ログイン画面の表示
Basic HTTP認証を使用してログインする。
header関数と$_SERVER変数を使用。
ログイン画面を表示後exitし、再度プラグインを開始することが必要。この処理の流れが分かるまで時間がかかった。
2. Logを作成する関数の作成
ログインなどを記録するための関数をdate関数とerror_log関数を使用して作成。
3. セッション処理をする関数(クラス)の作成
session_start、session_id、session_destroy関数と$_SESSION変数を使用して作成。
ここはセッションについて幾つかの処理があるのでクラスとしてまとめる。
上記3つの関数を共通ライブラリーとしてexpan.phpにまとめる。
また、今後共通関数の追加が必要な場合はexpan.phpを修正する。
expan.php
4. 管理者ログインプラグインの作成
上記関数を使用して、ログインしてセッションにログイン状態を保存するプラグインを作成する。
パスワードのチェックは既存のpkwk_hash_compute関数を使用。
ログイン方法が他人に分からないようにプラグイン名は添付のソースのファイル名とプラグイン名のxxxxxを適当に修正する。
ソースファイルを/var/www/pukiwiki/pluginディレクトリーに保存する。
使用方法は http://サーバー名/pukiwiki/?plugin=xxxxx ← xxxxxは修正後のプラグイン名
xxxxx.inc.php
5. 処理停止関数の作成
ログインしているか判断し、ログインしていない場合に処理を停止をする処理を各プラグインに入れると手間がかかるし、Pukiwikiのバージョンアップも困難になるので、plugin.phpを修正して、プラグインロード時にログインしているかどうか判断するようにする。
プラグインのaction用とconvert用にそれぞれcheck_plugin_action関数とcheck_plugin_convert関数を用意する。
この関数をexpan.phpに入れる。
メンテナンスし易いように、処理を停止するプラグインのリストを別ファイルに設定する。このリストに無い場合はOK(FALSEでreturn)とする。
処理停止の要否で問題があった場合、ソースの修正せずに大半はこのファイルの修正で対応可能。
- リストのフォーマット
プラグイン名:フラグ
フラグの値 | 説明 |
0 | TRUEでreturnする。プラグインの処理をSKIPするために使用 |
1 | die_message('Not Login')を実行し停止 |
- 処理停止関数リストファイルの保存場所
後記expan.phpの中に記述されているようにprohibit_action.lstとprohibit_convert.lstをpluginディレクトリー下に保存する。
prohibit_action.lst
prohibit_convert.lst
6. plugin.phpの修正
プラグインをロードするcall_user_func関数の前後をそれぞれの処理停止関数check_plugin_actionとcheck_plugin_convertで以下のように囲む。
:
:
function do_plugin_action($name)
{
:
if ( check_plugin_action( $name ) == FALSE ) { // K1 ← 追加する
$retvar = call_user_func('plugin_' . $name . '_action');
} // K1 ← 追加する
:
:
function do_plugin_convert($name, $args = '')
{
:
if ( check_plugin_convert( $name ) == FALSE ) { // K1 ← 追加する
$_digest = $digest;
$retvar = call_user_func_array('plugin_' . $name . '_convert', $aryargs);
$digest = $_digest; // Revert
} // K1 ← 追加する
:
:
注:plugin.phpをバージョンアップした時に、上書きされた場合同様の修正をすること。
plugin.php
7. 各プラグインの修正
- ) plugin.phpの修正では対応できなくて各プラグインにチェック処理を入れる場合は、例えばPKWK_READONLYの判断の後に以下ように処理を入れる。
:
:
if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
$obj = new expan_session(); ← 追加する
if (!$obj->check()) die_message('Not Login'); ← 追加する
:
:
- ) attach.inc.phpの修正
attachプラグインはpcmdパラメータにより処理が分かれていて、その処理別に管理者だけが操作できるように制限する必要があるので、以下のような処理を追加する。
:
:
case 'unfreeze':
if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
}
// K1 ↓ ← 追加の開始
switch ($pcmd) {
case 'delete': ↓以下管理者だけに許可する処理を列挙する
case 'info':
case 'unfreeze':
case 'rename':
case 'upload':
$obj = new expan_session();
if (!$obj->check()) {
die_message('Not Login');
}
}
// K1 ↑ ← 追加の終了
switch ($pcmd) {
case 'info' : return attach_info();
:
:
注:attach.inc.phpをバージョンアップした時に、上書きされた場合同様の修正をすること。
attach.inc.php
8. 設定
- ) pukiwiki.phpの修正
pukiwiki起動時にexpan.phpをロードするようにpukiwiki.phpを修正する。
# vi /var/www/pukiwiki/lib/pukiwiki.php
:
:
if ($trackback || $referer) {
// Referer functionality uses trackback functions
// without functional reason now
require(LIB_DIR . 'trackback.php'); // TrackBack
}
require(LIB_DIR . 'expan.php'); ← 追加する
/////////////////////////////////////////////////
// Main
$retvars = array();
:
:
- ) pukiwiki.ini.php中のユーザー設定
pukiwiki.ini.phpの中に設定されているユーザー名とパスワードを設定する。
:
// User definition
$auth_users = array(
// Username => password
'foo' => 'foo_passwd', // Cleartext
'bar' => '{x-php-md5}f53ae779077e987718cc285b14dfbe86', // PHP md5() 'bar_passwd'
'hoge' => '{SMD5}OzJo/boHwM4q5R+g7LCOx2xGMkFKRVEx', // LDAP SMD5 'hoge_passwd'
);
:
- ) expan.php中のglobal変数の修正
expan.phpの初めの部分に記述してある以下のglobal変数をシステムの構成に応じて修正する。
管理者のIPアドレスを制限する場合は、expan.phpの$auth_ipsにIPアドレスとユーザー名を以下のように設定する。ユーザー名はpukiwiki.ini.phpで設定したユーザー名と一致させる。
# vi /var/www/pukiwiki/lib/expan.php
:
$auth_ips = array( ← クライアントのIPアドレスとユーザー名の設定
// IP Address => Username
'192.168.1.100' => 'foo',
'192.168.1.101' => 'bar'
);
$log_file = '/var/log/httpd/pukiwiki.log'; ← ログファイル名の設定
$login_status = 'yyyyyyyy'; ← ログインの認証IDyyyyyyyyを適当に設定する
$action_filename = 'plugin/prohibit_action.lst';
$convert_filename = 'plugin/prohibit_convert.lst';
:
複数のPukiwikiを導入した時に上記$login_statusの値が同じだと、1つにログインすると他のPukiwikiも管理者として操作できてしまうので、別々に管理が必要な場合は、各Pukiwikiでこの値を変えて下さい。
上記の場合IPアドレスが'192.168.1.100'でユーザー名がfooとIPアドレスが'192.168.1.101'でユーザー名がbarでパスワードが正しい場合のみログイン可能である。
- ) ログファイル用ディレクトリーの作成
ログファイル用のディレクトリーを作成し、apacheにwrite権限を与える。
例:上記の$log_fileのディレクトリーを/var/log/pukiwikiに変更した場合
# mkdir /var/log/pukiwiki
# chown apache. /var/log/pukiwiki
注:デフォルトでは/var/log/httpdになっているのでこの操作は不要。
- ) 確認テスト
- ログインしないでブラウザーから http://サーバー名/pukiwiki/?cmd=edit&page=FrontPage にアクセスしてエラーメッセージ
Runtime error
Error message : Not Login
が表示されFrontPageが編集できなければ制限はOK。
- http://サーバー名/pukiwiki/?plugin=xxxxx にアクセスしてログイン出来、ページの更新ができればOK。
注:xxxxxは変更したPlugin名。